#ifndef VENUS_GRAPHICS_IMAGE_TEXTURE_GL_H
#define VENUS_GRAPHICS_IMAGE_TEXTURE_GL_H

#include "common/venus.h"
#include "opengl.h"

namespace venus {
enum ImageTextureGLOptions {
kUseMipmaps = 0x00000001,
kUseDefaultParameters = 0x00000002,
kDepthTexture = 0x00000004
};

class ImageTextureGL {
 public:
  ImageTextureGL(GLenum target = GL_TEXTURE_2D) 
      : target_(target), tex_id_(0) { }
  ~ImageTextureGL();
  void Enable() const { glEnable(target_); }
  void Disable() const { glDisable(target_); }
  void Bind() const;
  void Unbind() const;
  bool Initialize(int width, int height, GLuint internal_format, 
                  int opts = kUseDefaultParameters);
  bool Initialize(const Image &image, GLuint internal_format,
                  int opts = kUseDefaultParameters);
  void SetDefaultParameters();
  void SetParameter(GLenum name, GLint val) {
    glTexParameteri(target_, name, val);
  }
  void SetParameter(GLenum name, GLfloat val) {
    glTexParameterf(target_, name, val);
  }
  void SetParameter(GLenum name, GLfloat *val) {
    glTexParameterfv(target_, name, val);
  }
  void SetParameter(GLenum name, GLint *val) {
    glTexParameteriv(target_, name, val);
  }
  void Save(const char* filename) const;
  GLuint tex_id() const { return tex_id_; }
  GLenum target() const { return target_; }
  bool is_valid() const { return 0 != tex_id_; }
  int width() const { return width_; }
  int height() const { return height_; }
 private:
  bool BeginInitialize();
  void Release();
  bool AllocTexImage(GLuint internal_format, int width, int height,
                     GLint format, GLint type, const void *data);
 private:
  int width_, height_;
  GLuint tex_id_;
  GLenum target_;
};

} // namespace venus

#endif // VENUS_GRAPHICS_IMAGE_TEXTURE_GL_H
